﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autofac;
using Autofac.Builder;
#if NET40
using Microsoft.Practices.ServiceLocation;
using Autofac.Extras.DynamicProxy2;
#else
using CommonServiceLocator;
using Autofac.Extras.DynamicProxy;
#endif

namespace Mvvm.Common.Aop
{
   public static class AopExtensions
   {
       /// <summary>
       /// 是否注册aop
       /// </summary>
       private static bool _isRegisterAop=false;

       /// <summary>
       /// 注册aop
       /// </summary>
       /// <param name="builder"></param>
       public static ContainerBuilder RegisterAopInterceptor(this ContainerBuilder builder)
       {
           if (_isRegisterAop) return builder;
           builder.RegisterType<AopInterceptor>().AsSelf().SingleInstance();
           _isRegisterAop = true;

           return builder;
       }

       /// <summary>
        /// 注册aop InterfaceInterceptors
        /// </summary>
        /// <typeparam name="TLimit"></typeparam>
        /// <typeparam name="TActivatorData"></typeparam>
        /// <typeparam name="TStyle"></typeparam>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IRegistrationBuilder<TLimit, TActivatorData, TStyle> RegisterInterfaceInterceptors<TLimit, TActivatorData, TStyle>(
            this IRegistrationBuilder<TLimit, TActivatorData, TStyle> builder)
        {
            return builder.InterceptedBy(typeof(AopInterceptor)).EnableInterfaceInterceptors();
        }
        /// <summary>
        /// 注册aop ClassInterceptors
        /// </summary>
        /// <typeparam name="TLimit"></typeparam>
        /// <typeparam name="TActivatorData"></typeparam>
        /// <typeparam name="TStyle"></typeparam>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IRegistrationBuilder<TLimit, TActivatorData, TStyle> RegisterClassInterceptors<TLimit, TActivatorData, TStyle>(
            this IRegistrationBuilder<TLimit, TActivatorData, TStyle> builder) where TActivatorData : ConcreteReflectionActivatorData
        {
            return builder.InterceptedBy(typeof(AopInterceptor)).EnableClassInterceptors();
        }

        /// <summary>
        /// Injecting objects into properties marked with "AutofacResolve"
        /// </summary>
        /// <param name="attr">Source object</param>
        internal static void InjectProperties(AopBaseAttribute attr)
        {
            var propertiesToInject = attr.GetType().GetProperties().Where(m=>m.GetCustomAttributes(typeof(AopPropertiesInjectAttribute),false)?.Any()==true);
            foreach (var property in propertiesToInject)
            {
                var objectToInject = ServiceLocator.Current.GetInstance(property.PropertyType); 
                property.SetValue(attr, objectToInject, null);
            }
        }
    }
}
